//
//  YXModalViewController.m
//  YuanXinCamera
//
//  Created by wangxue on 2016/11/20.
//  Copyright © 2016年 晏德智. All rights reserved.
//

#import "YXModalViewController.h"
#import "YXPhotoPreviewController.h"
#import <SDWebImage/SDWebImage.h>
typedef NS_ENUM(BOOL, ModalTransitionDirection) {
    ModalTransitionDirectionPresenting = YES,
    ModalTransitionDirectionDismissing = NO
};
#define  kDurtion  0.5
@implementation YXModalViewController


#pragma mark -  Life Circle

- (instancetype)initWithThumbail:(CGRect)tappedThumbail {
    if (self = [super init]) {
        
        _tappedThumbnail = tappedThumbail;
       
    }
    return self;
}

#pragma mark - View controller animated transitioning

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    return kDurtion;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    if ([toViewController isKindOfClass:[YXPhotoPreviewController class]]) {
        [self performPresent:transitionContext];
    } else {
        [self performDismiss:transitionContext];
    }

    
}

#pragma mark - Performs
- (void)performPresent:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    YXPhotoPreviewController *presentedViewController = (YXPhotoPreviewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *presentedView = presentedViewController.view;
    UIView *containerView = [transitionContext containerView];
    
    [presentedView setAlpha:0.0];
    [containerView insertSubview:presentedView aboveSubview:containerView];
    
    UICollectionView *colletionview = presentedViewController.collectionView;
    
    CALayer *mask = [self maskWithPresenedViewFrame:presentedView.frame tappedThumbailFrame:self.tappedThumbnail direction:ModalTransitionDirectionPresenting animated:YES];
    [presentedView.layer setMask:mask];
    [presentedView setTransform:[self affineTransformWithImageViewFrame:presentedView.frame andThumbnailFrame:self.tappedThumbnail]];
    
    CGFloat duration = [self transitionDuration:transitionContext];
    [UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:0.7 initialSpringVelocity:0.0 options:0 animations:^{
        [presentedView setTransform:CGAffineTransformIdentity];
        [presentedView setAlpha:1.0];
    } completion:^(BOOL finished) {
      
        [transitionContext completeTransition:YES];
    }];

 
}
- (void)performDismiss:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    YXPhotoPreviewController *imageViewController = (YXPhotoPreviewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIView *containerView = [transitionContext containerView];
    UIView *fromView = imageViewController.view;
    

    [containerView addSubview:fromView];
    
    CGFloat duration = [self transitionDuration:transitionContext];
    
    CGRect freezeFrame = fromView.frame; // This is necessary if you want to delay the masking using dispatch_after
    CALayer *mask = [self maskWithPresenedViewFrame:freezeFrame tappedThumbailFrame:self.tappedThumbnail direction:ModalTransitionDirectionDismissing animated:YES];
   
    [fromView.layer setMask:mask];
    
    [UIView animateWithDuration:duration*0.2 delay:0.0 usingSpringWithDamping:1.0 initialSpringVelocity:1.0 options:0 animations:^{
        [fromView setTransform:[self affineTransformWithImageViewFrame:fromView.frame andThumbnailFrame:self.tappedThumbnail]];
        [fromView setAlpha:0.0];
    } completion:^(BOOL finished) {
       
        [transitionContext completeTransition:YES];
    }];

}

#pragma mark - private

- (BOOL)frameIsPortrait:(CGRect)bounds {
     return bounds.size.height > bounds.size.width;
    
}

- (CALayer *)maskWithPresenedViewFrame:(CGRect)viewframe
                   tappedThumbailFrame:(CGRect)tapframe
                             direction:(ModalTransitionDirection)direction
                              animated:(BOOL)animated {
    CGRect viewBounds = CGRectOffset(viewframe, -viewframe.origin.x, -viewframe.origin.y);
    CALayer *mask = [CALayer layer];
    mask.position = CGPointMake(CGRectGetMidX(viewBounds), CGRectGetMidY(viewBounds));
    mask.backgroundColor = [UIColor whiteColor].CGColor;
    
    CGRect maskBounds = [self maskBoundsWithViewFrame:viewframe andThumbnaiFrame:tapframe];
    if (animated) {
        mask.bounds = (direction == ModalTransitionDirectionPresenting?maskBounds : viewBounds);
    }
    mask.bounds = (direction == ModalTransitionDirectionPresenting ? viewBounds : maskBounds);
    
    return mask;
}

- (void)addAnimationToMask:(CALayer *)mask withMaskBounds:(CGRect)maskBounds viewBounds:(CGRect)viewBounds transitionDirection:(ModalTransitionDirection)direction {
    
    CABasicAnimation *maskBoundsAnimation = ^CABasicAnimation *{
        BOOL portrait = [self frameIsPortrait:viewBounds];
        NSString *keyPath = (portrait? @"bounds.size.height" : @"bounds.size.width");
        CGFloat maskBoundsDimension = (portrait ? maskBounds.size.height : maskBounds.size.width);
        CGFloat imageBoundsDimension = (portrait ? viewBounds.size.height : viewBounds.size.width);
        
        CGFloat fromValue = (direction == ModalTransitionDirectionPresenting ? maskBoundsDimension : imageBoundsDimension);
        CGFloat toValue = (direction == ModalTransitionDirectionPresenting ? imageBoundsDimension : maskBoundsDimension);
        
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath];
        animation.fromValue = @(fromValue);
        animation.toValue = @(toValue);
        animation.duration = kDurtion;
        
        return animation;

       
    }();
    [mask addAnimation:maskBoundsAnimation forKey:@"bounds"];

    
}

- (CGRect)maskBoundsWithViewFrame:(CGRect)viewFrame
                 andThumbnaiFrame:(CGRect)thumbframe {
    CGSize viewSize = viewFrame.size;
    CGFloat viewRation = viewFrame.size.width / viewFrame.size.height;
    CGFloat thumbnailRation = thumbframe.size.width / thumbframe.size.height;
    
    CGFloat x = 0.0;
    CGFloat y = 0.0;
    CGFloat width = 0.0;
    CGFloat height = 0.0;
    
    if (thumbnailRation > viewRation) { // Top-bottom cropping
        width = viewSize.width;
        height = width / thumbnailRation;
        y = (viewSize.height - height) / 2.0;
    } else {                               // Left-right cropping
        height = viewSize.height;
        width = height * thumbnailRation;
        x = (viewSize.width - width) / 2.0;
    }
    
    return CGRectMake(x, y, width, height);

}

- (CGFloat)scaleFactorForViewFrame:(CGRect)viewFrame andThumbnailFrame:(CGRect)thumbnailFrame {
    
    CGFloat factor;
    
    CGFloat const imageRatio = viewFrame.size.width / viewFrame.size.height;
    CGFloat const thumbnailRatio = thumbnailFrame.size.width / thumbnailFrame.size.height;
    
    if (thumbnailRatio > imageRatio) {
        factor = thumbnailFrame.size.width / viewFrame.size.width;
    } else {
        factor = thumbnailFrame.size.height / viewFrame.size.height;
    }
    
    return factor;
}
- (CGAffineTransform)affineTransformWithImageViewFrame:(CGRect)imageViewFrame andThumbnailFrame:(CGRect)thumbnailFrame {
    
    CGFloat scaleFactor = [self scaleFactorForViewFrame:imageViewFrame andThumbnailFrame:thumbnailFrame];
    CGAffineTransform scale = CGAffineTransformMakeScale(scaleFactor, scaleFactor);
    
    CGFloat deltaX = CGRectGetMidX(thumbnailFrame) - CGRectGetMidX(imageViewFrame);
    CGFloat deltaY = CGRectGetMidY(thumbnailFrame) - CGRectGetMidY(imageViewFrame);
    CGAffineTransform translation = CGAffineTransformMakeTranslation(deltaX, deltaY);
    
    return CGAffineTransformConcat(scale, translation);
}

@end
